home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / filesyst / ncpfs / ipxripd-.000 / ipxripd- / ipxripd / ipxsap.c < prev    next >
C/C++ Source or Header  |  1996-02-08  |  7KB  |  315 lines

  1. /*
  2.    IPX support library - SAP
  3.  
  4.    Copyright (C) 1994, 1995  Ales Dryak <e-mail: A.Dryak@sh.cvut.cz>
  5.    Copyright (C) 1996, Volker Lendecke <lendecke@namu01.gwdg.de>
  6.  
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2 of the License, or
  10.    (at your option) any later version.
  11.  
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  */
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <sys/socket.h>
  25. #include <netinet/in.h>
  26. #include "ipxsap.h"
  27. #include "ipxd.h"
  28.  
  29. int 
  30. ipx_sap_size(int n, unsigned short int operation)
  31. {
  32.     if (n <= 0)
  33.     {
  34.         return 0;
  35.     }
  36.  
  37.     switch (operation)
  38.     {
  39.     case IPX_SAP_OP_REQUEST:
  40.         return n == 1 ? IPX_SAP_REQUEST_LEN : 0;
  41.  
  42.     case IPX_SAP_OP_RESPONSE:
  43.         if (n > IPX_SAP_MAX_ENTRIES)
  44.         {
  45.             return 0;
  46.         }
  47.         return (2 + n * sizeof(struct sap_entry));
  48.  
  49.     case IPX_SAP_OP_GNS_REQUEST:
  50.         return n == 1 ? IPX_SAP_REQUEST_LEN : 0;
  51.  
  52.     case IPX_SAP_OP_GNS_RESPONSE:
  53.         return n == 1 ? 2 + sizeof(struct sap_entry) : 0;
  54.         break;
  55.     default:
  56.         return 0;
  57.     }
  58. }
  59.  
  60. void 
  61. ipx_sap_assign_ser_name(ser_name_t dest, ser_name_t src)
  62. {
  63.     memset(dest, 0, IPX_SAP_SERVER_NAME_LEN);
  64.     strncpy(dest, src, IPX_SAP_SERVER_NAME_LEN);
  65. }
  66.  
  67. int 
  68. ipx_sap_name_equal(ser_name_t n1, ser_name_t n2)
  69. {
  70.     return strncmp(n1, n2, IPX_SAP_SERVER_NAME_LEN) == 0;
  71. }
  72.  
  73. int 
  74. ipx_sap_type_equal(ser_type_t t1, ser_type_t t2)
  75. {
  76.     return t1==IPX_SAP_GENERAL_RQ || t2==IPX_SAP_GENERAL_RQ || t1 == t2;
  77. }
  78.  
  79. static int
  80. ipx_sap_sendto(int sock, void *buffer, int size, struct sockaddr_ipx *daddr)
  81. {
  82.     
  83.     if (ipx_sap_output_func != NULL)
  84.     {
  85.         return ipx_sap_output_func(sock, buffer, size, daddr);
  86.     }
  87.     return 0;
  88. }
  89.  
  90. int 
  91. ipx_sap_output_init(struct sap_output *out, IPXNet net)
  92. {
  93.     out->entries = 0;
  94.     out->send_error = 0;
  95.     out->buffer.operation = htons(IPX_SAP_OP_REQUEST);
  96.     out->dest_addr.sipx_family = AF_IPX;
  97.     out->dest_addr.sipx_type = IPX_SAP_PTYPE;
  98.     out->dest_addr.sipx_network = htonl(net);
  99.     return 0;
  100. }
  101.  
  102. void 
  103. ipx_sap_output_flush(struct sap_output * out)
  104. {
  105.     if (out->entries == 0)
  106.     {
  107.         return;
  108.     }
  109.     if (out->send_error != 0)
  110.     {
  111.         out->entries = 0;
  112.         return;
  113.     }
  114.     if (ipx_sap_sendto(out->sk, &(out->buffer),
  115.                ipx_sap_size(out->entries,
  116.                     ntohs(out->buffer.operation)),
  117.                &(out->dest_addr)) < 0)
  118.     {
  119.         out->send_error = 1;
  120.         check_request = 1;
  121.     }
  122.     out->entries = 0;
  123. }
  124.  
  125. void 
  126. ipx_sap_output_request(struct sap_output * out, ser_type_t ser_type)
  127. {
  128.     struct sap_entry *se;
  129.     ipx_sap_output_flush(out);
  130.     out->buffer.operation = htons(IPX_SAP_OP_REQUEST);
  131.     se = &(out->buffer.sap_entries[out->entries]);
  132.     se->ser_type = htons(ser_type);
  133.     out->entries++;
  134. }
  135.  
  136. void 
  137. ipx_sap_output_gns_request(struct sap_output * out, ser_type_t ser_type)
  138. {
  139.     struct sap_entry *se;
  140.     ipx_sap_output_flush(out);
  141.     out->buffer.operation = htons(IPX_SAP_OP_GNS_REQUEST);
  142.     se = &(out->buffer.sap_entries[out->entries]);
  143.     se->ser_type = htons(ser_type);
  144.     out->entries++;
  145. }
  146.  
  147. void 
  148. ipx_sap_output_response(struct sap_output * out, ser_type_t type,
  149.             ser_name_t name, struct sockaddr_ipx *addr,
  150.             hop_t hops, int down_allow)
  151. {
  152.     struct sap_entry *se;
  153.  
  154.     if (hops >= IPX_SAP_SERVER_DOWN && !down_allow)
  155.     {
  156.         return;
  157.     }
  158.     if (out->entries >= IPX_SAP_MAX_ENTRIES)
  159.     {
  160.         ipx_sap_output_flush(out);
  161.     }
  162.     if (out->buffer.operation != htons(IPX_SAP_OP_RESPONSE))
  163.     {
  164.         ipx_sap_output_flush(out);
  165.         out->buffer.operation = htons(IPX_SAP_OP_RESPONSE);
  166.     }
  167.  
  168.     if (passive != 0)
  169.     {
  170.         return;
  171.     }
  172.  
  173.     se = &(out->buffer.sap_entries[out->entries]);
  174.     se->ser_type = htons(type);
  175.     ipx_sap_assign_ser_name(se->ser_name, name);
  176.     se->network = addr->sipx_network;
  177.     ipx_assign_node(se->node, addr->sipx_node);
  178.     se->port = addr->sipx_port;
  179.     se->hops = htons(hops);
  180.     out->entries++;
  181. }
  182.  
  183. void 
  184. ipx_sap_output_gns_response(struct sap_output * out,
  185.                 ser_type_t type, ser_name_t name,
  186.                 struct sockaddr_ipx *addr, hop_t hops)
  187. {
  188.     struct sap_entry *se;
  189.  
  190.     if (hops >= IPX_SAP_SERVER_DOWN)
  191.     {
  192.         return;
  193.     }
  194.  
  195.     ipx_sap_output_flush(out);
  196.  
  197.     if (passive != 0)
  198.     {
  199.         return;
  200.     }
  201.     
  202.     out->buffer.operation = htons(IPX_SAP_OP_GNS_RESPONSE);
  203.     se = &(out->buffer.sap_entries[out->entries]);
  204.     se->ser_type = htons(type);
  205.     ipx_sap_assign_ser_name(se->ser_name, name);
  206.     se->network = addr->sipx_network;
  207.     ipx_assign_node(se->node, addr->sipx_node);
  208.     se->port = addr->sipx_port;
  209.     se->hops = htons(hops);
  210.     out->entries++;
  211. }
  212.  
  213. void 
  214. ipx_sap_output_set_destination(struct sap_output * out,
  215.                    IPXNode node, IPXPort port)
  216. {
  217.     ipx_sap_output_flush(out);
  218.     ipx_assign_node(out->dest_addr.sipx_node, node);
  219.     out->dest_addr.sipx_port = htons(port);
  220. }
  221.  
  222. void 
  223. ipx_sap_fprint_name(FILE * file, char *sname)
  224. {
  225.     char name[IPX_SAP_SERVER_NAME_LEN + 1];
  226.     int len;
  227.  
  228.     memcpy(name, sname, IPX_SAP_SERVER_NAME_LEN);
  229.     name[IPX_SAP_SERVER_NAME_LEN] = 0;
  230.     len = strlen(name);
  231.     memset(name + len, ' ', IPX_SAP_SERVER_NAME_LEN - len);
  232.     fprintf(file, name);
  233. }
  234.  
  235. static void 
  236. fprint_entry(FILE * file, struct sap_entry *se)
  237. {
  238.     fprintf(file, "SAP: type: %04X name: ", ntohs(se->ser_type));
  239.     ipx_sap_fprint_name(file, se->ser_name);
  240.     fprintf(file, " \nhops: %i addr: ", ntohs(se->hops));
  241.     ipx_fprint_network(file, ntohl(se->network));
  242.     fprintf(file, ":");
  243.     ipx_fprint_node(file, se->node);
  244.     fprintf(file, ":");
  245.     ipx_fprint_port(file, ntohs(se->port));
  246.     fprintf(file, "\n");
  247. }
  248.  
  249. void 
  250. ipx_sap_dump(struct sap_packet *pkt, int len)
  251. {
  252.     ipx_sap_fdump(stdout, pkt, len);
  253. }
  254.  
  255. void 
  256. ipx_sap_fdump(FILE * file, struct sap_packet *pkt, int len)
  257. {
  258.     int ent;
  259.     struct sap_entry *se = pkt->sap_entries;
  260.  
  261.     if (len < 2)
  262.     {
  263.         return;
  264.     }
  265.  
  266.     fprintf(file, "Operation: %i size: %i ", ntohs(pkt->operation), len);
  267.     switch (ntohs(pkt->operation))
  268.     {
  269.     case IPX_SAP_OP_REQUEST:
  270.         fprintf(file, "(Request)\n");
  271.         if (ipx_sap_size(1, IPX_SAP_OP_REQUEST) != len)
  272.         {
  273.             fprintf(file, "Warning: Bad SAP size\n");
  274.         }
  275.         fprintf(file, "SAP: Type: %04X\n", ntohs(se->ser_type));
  276.         break;
  277.     case IPX_SAP_OP_GNS_REQUEST:
  278.         fprintf(file, "(Get Nearest Server Request)\n");
  279.         if (ipx_sap_size(1, IPX_SAP_OP_GNS_REQUEST) != len)
  280.         {
  281.             fprintf(file, "Warning: Bad SAP size\n");
  282.         }
  283.         fprintf(file, "SAP: Type: %04X\n", ntohs(se->ser_type));
  284.         break;
  285.     case IPX_SAP_OP_RESPONSE:
  286.  
  287.         fprintf(file, "(Response)\n");
  288.         ent = (len - 2) / sizeof(struct sap_entry);
  289.  
  290.         if (ipx_sap_size(ent, IPX_SAP_OP_RESPONSE) != len)
  291.         {
  292.             fprintf(file, "Warning: Bad SAP size\n");
  293.         }
  294.         for (; ent--; se++)
  295.         {
  296.             fprint_entry(file, se);
  297.         }
  298.         break;
  299.     case IPX_SAP_OP_GNS_RESPONSE:
  300.         fprintf(file, "(Get Nearest Server Response)\n");
  301.         if (ipx_sap_size(1, IPX_SAP_OP_RESPONSE) != len)
  302.         {
  303.             fprintf(file, "Warning: Bad SAP size\n");
  304.         }
  305.         fprint_entry(file, se);
  306.         break;
  307.     default:
  308.         fprintf(file, "(Unknown)\n");
  309.         break;
  310.     }
  311. }
  312.  
  313. int (*ipx_sap_output_func) (int sock, void *, int, struct sockaddr_ipx *)
  314.     = NULL;
  315.